package user

import (
	"context"
	"fmt"

	"github.com/star-find-cloud/star-safe/pkg/logger"
	"golang.org/x/crypto/bcrypt"
)

// Service 用户服务接口
type Service interface {
	CreateUser(ctx context.Context, req *CreateUserRequest) (*UserResponse, error)
	GetUserByID(ctx context.Context, id int64) (*UserResponse, error)
	GetUserByUsername(ctx context.Context, username string) (*UserResponse, error)
	GetUserByEmail(ctx context.Context, email string) (*UserResponse, error)
	UpdateUser(ctx context.Context, id int64, req *UpdateUserRequest) error
	DeleteUser(ctx context.Context, id int64) error
	ListUsers(ctx context.Context, page, pageSize int) ([]*UserResponse, int64, error)
	VerifyPassword(ctx context.Context, username, password string) (*UserResponse, error)
}

type userService struct {
	repo Repository
}

// NewService 创建用户服务实例
func NewService(repo Repository) Service {
	return &userService{
		repo: repo,
	}
}

// CreateUser 创建用户
func (s *userService) CreateUser(ctx context.Context, req *CreateUserRequest) (*UserResponse, error) {
	// 检查用户名是否已存在
	existingUser, err := s.repo.GetByUsername(ctx, req.Username)
	if err != nil {
		// 如果是"用户不存在"的错误，继续创建
		if err.Error() == "用户不存在" || err.Error() == "sql: no rows in result set" {
			// 用户不存在，可以继续创建
		} else {
			logger.MySQLLogger.Errorf("查询用户名失败: %v", err)
			return nil, fmt.Errorf("系统错误，请稍后重试")
		}
	}
	if existingUser != nil {
		return nil, fmt.Errorf("用户名已存在")
	}

	// 检查邮箱是否已存在
	existingEmail, err := s.repo.GetByEmail(ctx, req.Email)
	if err != nil {
		// 如果是"用户不存在"的错误，继续创建
		if err.Error() == "用户不存在" || err.Error() == "sql: no rows in result set" {
			// 用户不存在，可以继续创建
		} else {
			logger.MySQLLogger.Errorf("查询邮箱失败: %v", err)
			return nil, fmt.Errorf("系统错误，请稍后重试")
		}
	}
	if existingEmail != nil {
		return nil, fmt.Errorf("邮箱已存在")
	}

	// 加密密码
	hashedPassword, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
	if err != nil {
		logger.MySQLLogger.Errorf("密码加密失败: %v", err)
		return nil, fmt.Errorf("系统错误，请稍后重试")
	}

	// 创建用户
	user := &User{
		Username: req.Username,
		Email:    req.Email,
		Password: string(hashedPassword),
		Phone:    req.Phone,
		Status:   1, // 默认启用状态
	}

	err = s.repo.Create(ctx, user)
	if err != nil {
		return nil, err
	}

	return s.toUserResponse(user), nil
}

// GetUserByID 根据ID获取用户
func (s *userService) GetUserByID(ctx context.Context, id int64) (*UserResponse, error) {
	user, err := s.repo.GetByID(ctx, id)
	if err != nil {
		return nil, err
	}

	return s.toUserResponse(user), nil
}

// GetUserByUsername 根据用户名获取用户
func (s *userService) GetUserByUsername(ctx context.Context, username string) (*UserResponse, error) {
	user, err := s.repo.GetByUsername(ctx, username)
	if err != nil {
		return nil, err
	}

	return s.toUserResponse(user), nil
}

// GetUserByEmail 根据邮箱获取用户
func (s *userService) GetUserByEmail(ctx context.Context, email string) (*UserResponse, error) {
	user, err := s.repo.GetByEmail(ctx, email)
	if err != nil {
		return nil, err
	}

	return s.toUserResponse(user), nil
}

// UpdateUser 更新用户信息
func (s *userService) UpdateUser(ctx context.Context, id int64, req *UpdateUserRequest) error {
	// 检查用户是否存在
	_, err := s.repo.GetByID(ctx, id)
	if err != nil {
		return err
	}

	// 如果更新用户名，检查是否重复
	if req.Username != "" {
		existingUser, err := s.repo.GetByUsername(ctx, req.Username)
		if err != nil {
			// 如果是"用户不存在"的错误，继续更新
			if err.Error() == "用户不存在" || err.Error() == "sql: no rows in result set" {
				// 用户不存在，可以继续更新
			} else {
				logger.MySQLLogger.Errorf("查询用户名失败: %v", err)
				return fmt.Errorf("系统错误，请稍后重试")
			}
		}
		if existingUser != nil && existingUser.ID != id {
			return fmt.Errorf("用户名已存在")
		}
	}

	// 如果更新邮箱，检查是否重复
	if req.Email != "" {
		existingEmail, err := s.repo.GetByEmail(ctx, req.Email)
		if err != nil {
			// 如果是"用户不存在"的错误，继续更新
			if err.Error() == "用户不存在" || err.Error() == "sql: no rows in result set" {
				// 用户不存在，可以继续更新
			} else {
				logger.MySQLLogger.Errorf("查询邮箱失败: %v", err)
				return fmt.Errorf("系统错误，请稍后重试")
			}
		}
		if existingEmail != nil && existingEmail.ID != id {
			return fmt.Errorf("邮箱已存在")
		}
	}

	return s.repo.Update(ctx, id, req)
}

// DeleteUser 删除用户
func (s *userService) DeleteUser(ctx context.Context, id int64) error {
	return s.repo.Delete(ctx, id)
}

// ListUsers 分页获取用户列表
func (s *userService) ListUsers(ctx context.Context, page, pageSize int) ([]*UserResponse, int64, error) {
	users, total, err := s.repo.List(ctx, page, pageSize)
	if err != nil {
		return nil, 0, err
	}

	var responses []*UserResponse
	for _, user := range users {
		responses = append(responses, s.toUserResponse(user))
	}

	return responses, total, nil
}

// VerifyPassword 验证用户名和密码
func (s *userService) VerifyPassword(ctx context.Context, username, password string) (*UserResponse, error) {
	user, err := s.repo.GetByUsername(ctx, username)
	if err != nil {
		return nil, fmt.Errorf("用户名或密码错误")
	}

	// 验证密码
	err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password))
	if err != nil {
		return nil, fmt.Errorf("用户名或密码错误")
	}

	// 检查用户状态
	if user.Status == 0 {
		return nil, fmt.Errorf("用户已被禁用")
	}

	return s.toUserResponse(user), nil
}

// toUserResponse 转换用户模型到响应格式
func (s *userService) toUserResponse(user *User) *UserResponse {
	return &UserResponse{
		ID:        user.ID,
		Username:  user.Username,
		Email:     user.Email,
		Phone:     user.Phone,
		Status:    user.Status,
		CreatedAt: user.CreatedAt,
		UpdatedAt: user.UpdatedAt,
	}
}
